package core

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"math/big"
	"net"
	"os"
	"path/filepath"
	"time"
)

// TLSManager TLS证书管理器
type TLSManager struct {
	certPath string
	keyPath  string
}

// NewTLSManager 创建TLS管理器
func NewTLSManager(dataDir string) *TLSManager {
	return &TLSManager{
		certPath: filepath.Join(dataDir, "cert.pem"),
		keyPath:  filepath.Join(dataDir, "key.pem"),
	}
}

// EnsureCertificates 确保证书存在（不存在则生成）
func (tm *TLSManager) EnsureCertificates() error {
	// 检查证书是否已存在
	if tm.certificatesExist() {
		return nil
	}

	// 生成新证书
	return tm.generateCertificates()
}

// certificatesExist 检查证书文件是否存在
func (tm *TLSManager) certificatesExist() bool {
	_, certErr := os.Stat(tm.certPath)
	_, keyErr := os.Stat(tm.keyPath)
	return certErr == nil && keyErr == nil
}

// generateCertificates 生成自签名证书
func (tm *TLSManager) generateCertificates() error {
	// 生成RSA私钥（2048位）
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		return err
	}

	// 证书模板
	template := x509.Certificate{
		SerialNumber: big.NewInt(1),
		Subject: pkix.Name{
			Organization: []string{"LAN File Transfer"},
			CommonName:   "localhost",
		},
		NotBefore:             time.Now(),
		NotAfter:              time.Now().Add(365 * 24 * time.Hour), // 有效期1年
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
		BasicConstraintsValid: true,
	}

	// 添加所有可能的IP地址和域名
	template.IPAddresses = []net.IP{
		net.ParseIP("127.0.0.1"),
		net.ParseIP("::1"),
	}

	// 添加本机所有局域网IP
	localIPs := GetLocalIPs()
	for _, ip := range localIPs {
		template.IPAddresses = append(template.IPAddresses, net.ParseIP(ip))
	}

	// 添加域名
	template.DNSNames = []string{
		"localhost",
		"*.local",
	}

	// 生成自签名证书
	certBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
	if err != nil {
		return err
	}

	// 保存证书
	certOut, err := os.Create(tm.certPath)
	if err != nil {
		return err
	}
	defer certOut.Close()

	if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certBytes}); err != nil {
		return err
	}

	// 保存私钥
	keyOut, err := os.Create(tm.keyPath)
	if err != nil {
		return err
	}
	defer keyOut.Close()

	privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)
	if err := pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: privateKeyBytes}); err != nil {
		return err
	}

	return nil
}

// GetCertPath 获取证书路径
func (tm *TLSManager) GetCertPath() string {
	return tm.certPath
}

// GetKeyPath 获取私钥路径
func (tm *TLSManager) GetKeyPath() string {
	return tm.keyPath
}
